// **************************************************************
// COPYRIGHT(c)2020, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    : 
// Module name  : 
// Full name    :  
//
// Author       : Hbing
// Email        : 2629029232@qq.com
// Data         : 2020/8/26
// Version      : V 1.0 
// 
// Abstract     : 
// Called by    :  
// 
// Modification history
// -----------------------------------------------------------------
// V2.0 考虑把把物理队长的更新以及对应端口是否有数据帧的bit掩码表放在此模块更新
// 
// 
// *****************************************************************
`include "top_define.v"
// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// DESCRIPTION
// *******************
// 初步设想--两个独立的状态机，一个用来从分组处理搬移数据到一个FIFO中
//                          另一个用来根据sr_rx_fifo结果将FIFO中数据搬移至片内缓存
// 
//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
//*******************
module bus_master_rx(
    //sysrem input/output
    input  wire         clk  ,
    input  wire         rst_n,
    input  wire [9:0]   ram_2p_cfg_register,
    //with enqueue_result_fifo
    input  wire         enqueue_result_fifo_empty,
    output reg          enqueue_result_fifo_rden ,
    input  wire         enqueue_result_fifo_rdata,
    //with schedule_enqueue
    /*(*mark_debug = "true"*)*/ input  wire         sr_rx_fifo_empty,
    /*(*mark_debug = "true"*)*/ output reg          sr_rx_fifo_rden ,
    /*(*mark_debug = "true"*)*/ input  wire [ 39:0] sr_rx_fifo_rdata,
    //with frame_process
    input  wire         trans_ready   ,
    output reg          trans_start   ,
	output reg 			discard_start ,
    input  wire         frame_rd_end  ,
    input  wire [255:0] bus_data_i    ,
    input  wire         bus_data_val_i,
    //input  wire         bus_data_end_i,
    //input  wire [ 10:0] frame_len_bus ,  //无用？？？
    //with SRAM_memory
    /*(*mark_debug = "true"*)*/ output reg  [ 13:0] memory_waddr,
    /*(*mark_debug = "true"*)*/ output reg          memory_wren ,
    /*(*mark_debug = "true"*)*/ output reg  [255:0] memory_wdata,
    //with queue_infor_management
    output reg          queue_indicate_ram_init_done,  //物理队长RAM初始化完毕
    output reg  [  2:0] enqueue_indicate_length_wr_addr,  //端口号，0-3代表单播，4代表多播
    output reg  [ 63:0] enqueue_indicate_length_wr_data,  //物理队长写数据，不同优先级从高到低存在RAM同一地址
    output reg          enqueue_indicate_length_wr_en  ,
    input  wire [ 63:0] enqueue_indicate_length_rd_data,
    input  wire [  2:0] dequeue_indicate_length_wr_addr       ,  //防冲突更新
    input  wire [ 63:0] dequeue_indicate_length_wr_data        ,
    input  wire         dequeue_indicate_length_wr_en       ,
    //with port_state_bit_mux
    output reg  [  2:0] port_state_bit_set , //更新对应端口位置的bit掩码表--用于出队快速判断哪个端口有数据
    output reg          port_state_bit_val
);
//*******************
//DEFINE LOCAL PARAMETER
//*******************
//parameter(s)
//fist_state_machine--frame_process -> rx_data_fifo
localparam TRANS_IDLE       = 4'b0000;
localparam READ_RESULT_FIFO = 4'b0001;
localparam TRANS_DATA       = 4'b0010;
localparam TRANS_DISCARD    = 4'b0100;
localparam TRANS_FINISH     = 4'b1000;
//fist_state_machine--rx_data_fifo -> SRAM_memory
localparam IDLE         = 5'b00000;
localparam INIT         = 5'b00001;  //物理队长RAM初始化
localparam WRITE_MEMORY = 5'b00010;
localparam WRITE_WAIT   = 5'b00100;
localparam WRITE_FINISH = 5'b01000;
//sr_rx_fifo
// _ _ _ 4 _ _ _ _ _ _ _ 6 _ _ _ _ _ _ _ 11 _ _ _ _ _ _ 1 _ _ _ _ _ 1 _ _ _  _ _12 _ _ _  _ _ 4_ _ _
//|    39~36   |       35~30      |    29~19     |     18    |     17    |     16~4     |    3~0    |
//|___reserve__|__enqueue_number__|_frame_length_|__first_BD_|__last_BD__|__BD_address__|__buf_num__|

//*********************
//INNER SIGNAL DECLARATION--1
//*********************
//REGS
//第一个状态机--根据入队结果将数据帧从分组处理中搬移至此模块一个暂存FIFO中
(*mark_debug = "true"*) reg [3:0] cstate,nstate;
//rx_data_fifo读使能
/*(*mark_debug = "true"*)*/ reg rx_data_fifo_rden;
//reg [10:0]	frame_len_bus_dl 			;

reg         enqueue_result_fifo_rdata_reg;
reg         enqueue_result_fifo_empty_reg;
//寄存 rx_data
/*(*mark_debug = "true"*)*/ reg [255:0] rx_data_fifo_rdata_reg;
/*(*mark_debug = "true"*)*/ reg         rx_data_fifo_empty_reg;
//寄存 sr_rx_data
reg [ 39:0] sr_rx_fifo_rdata_reg;
reg         sr_rx_fifo_empty_reg;
//WIRES
/*(*mark_debug = "true"*)*/ wire         rx_ready;
//rx_data_fifo
// wire         rx_data_fifo_wren ;
/*(*mark_debug = "true"*)*/ wire         rx_data_fifo_empty;
wire         rx_data_fifo_full ;
/*(*mark_debug = "true"*)*/ wire [255:0] rx_data_fifo_rdata;
//*********************
//INNER SIGNAL DECLARATION--2
//*********************
//REGS
//第二个状态机--根据接收调度结果将数据帧从暂存FIFO中搬移至片内SRAM中r

(*mark_debug = "true"*) reg [4:0] c_state,n_state;
reg rd_fifo_dl;
(*mark_debug = "true"*) reg wr_mem;
//寄存sr_rx_fifo信息
// reg [ 5:0] enqueue_number;
(*mark_debug = "true"*) reg [ 2:0] enqueue_NodeID;
(*mark_debug = "true"*) reg [ 2:0] enqueue_pri;

//WRITE_MEMORY状态计数
(*mark_debug = "true"*) reg [1:0]  write_memory_cnt;
//写数据帧计数，256bit位宽，一次32byte
// (*mark_debug = "true"*) reg [10:0] write_frame_cnt;
//写一帧最后一个BD标志--只在write_memory_cnt==2'd2维持一拍
reg last_BD_reg;
reg first_BD_reg;
//WIRES
(*mark_debug = "true"*) wire last_BD;
(*mark_debug = "true"*) wire first_BD;
wire [10:0] frame_length_sub;
(*mark_debug = "true"*) wire rx_rd_stop;
//*********************
//INSTANTCE MODULE
//*********************
// assign rx_data_fifo_wren = (cstate == TRANS_DATA) ? bus_data_val_i : 1'b0 ;

`ifdef ASIC 
rx_data_fifo U_fifo_w256_d128_asic(
    .clock         (clk)           ,
    .rst_n         (rst_n)           ,
    .ram_2p_cfg_register(ram_2p_cfg_register),
    .fifo_wen      (bus_data_val_i)           ,
    .fifo_wdata    (bus_data_i)           ,
    .fifo_ren      (rx_data_fifo_rden)           ,
    .fifo_rdata    (rx_data_fifo_rdata)           ,
    .fifo_empty_rd (rx_data_fifo_empty)           ,
    .fifo_full_wr  ()           ,
    .almost_full   (rx_data_fifo_full)
);
`else
rx_data_fifo_ip U_fifo_w256_d128 (
    .clk           (clk),
    .rst           (~rst_n),
    .wr_en         (bus_data_val_i),
    .din           (bus_data_i),
    .rd_en         (rx_data_fifo_rden),
    .dout          (rx_data_fifo_rdata),
    .empty         (rx_data_fifo_empty),
    .full          (),
    .prog_full     (rx_data_fifo_full)
    );

`endif
//*********************
//MAIN CORE
//********************* 
//always @(posedge clk or negedge rst_n) begin
//	if(~rst_n) begin
//		frame_len_bus_dl <= 1'b0;
//	end
//	else begin
//	    frame_len_bus_dl <= frame_len_bus;
//	end
//end

//rx_数据打拍
always @(posedge clk or negedge rst_n) begin
	if(~rst_n) begin
		enqueue_result_fifo_rdata_reg <= 1'b0;
		enqueue_result_fifo_empty_reg <= 1'b1;
	end
	else begin
	    enqueue_result_fifo_rdata_reg <= enqueue_result_fifo_rdata;
	    enqueue_result_fifo_empty_reg <= enqueue_result_fifo_empty;	
	end
end

always @(posedge clk) begin
	if(~rst_n) begin
		rd_fifo_dl <= 1'b0;
	end
	else begin
		rd_fifo_dl <= (((c_state == WRITE_MEMORY) || c_state == WRITE_FINISH)? 1'b1:1'b0);
	end
end

always @(posedge clk) begin
 	if(~rst_n) begin
 		wr_mem <= 1'b0;
 	end
 	else begin
    	wr_mem <= rd_fifo_dl;
    end
end

//从分组处理搬移数据至暂存FIFO状态机
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        cstate <= TRANS_IDLE;
    end
    else begin
        cstate <= nstate;
    end
end
assign rx_ready = (enqueue_result_fifo_empty_reg == 1'b0) && (enqueue_result_fifo_empty == 1'b0) && (rx_data_fifo_full == 1'b0) && (trans_ready == 1'b1);
always @(*) begin
    case(cstate)
        TRANS_IDLE:
        begin
            if (rx_ready) begin
                nstate = READ_RESULT_FIFO;
            end
            else begin
                nstate = TRANS_IDLE;
            end
        end
        READ_RESULT_FIFO:
        begin
            if (enqueue_result_fifo_rdata_reg == 1'b1) begin
                nstate = TRANS_DATA;
            end
            else begin
                nstate = TRANS_DISCARD;
            end
        end
        TRANS_DATA:
        begin
            if(frame_rd_end) begin
                if (rx_ready) begin
                    nstate = READ_RESULT_FIFO;
                end
                else begin
                    nstate = TRANS_IDLE;
                end
            end
            else begin
                nstate = TRANS_DATA;
            end
        end
        TRANS_DISCARD:
        begin
            if(frame_rd_end) begin
                if (rx_ready) begin
                    nstate = READ_RESULT_FIFO;
                end
                else begin
                    nstate = TRANS_IDLE;
                end
            end
            else begin
                nstate = TRANS_DISCARD;
            end
        end
        default:
        begin
            nstate = TRANS_IDLE;
        end
    endcase
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        trans_start <= 1'b0;
    end
    else if (rx_ready && (~trans_start)) begin
        trans_start <= 1'b1;
    end
    else begin
        trans_start <= 1'b0;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        discard_start <= 1'b0;
    end
    else if (rx_ready && (~trans_start) && (~enqueue_result_fifo_rdata_reg)) begin
        discard_start <= 1'b1;
    end
    else begin
        discard_start <= 1'b0;
    end
end


//拉高enqueue_result_fifo读使能
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        enqueue_result_fifo_rden <= 1'b0;
    end
    else if (cstate == READ_RESULT_FIFO) begin
        enqueue_result_fifo_rden <= 1'b1;
    end
    else begin
        enqueue_result_fifo_rden <= 1'b0;
    end
end
/**************************************************************/
assign first_BD = sr_rx_fifo_rdata_reg[18] & (~sr_rx_fifo_empty_reg);
assign last_BD  = sr_rx_fifo_rdata_reg[17] & (~sr_rx_fifo_empty_reg);
//rx_数据打拍
always @(posedge clk) begin
	if(~rst_n) begin
		rx_data_fifo_rdata_reg  <= 256'b0;
		sr_rx_fifo_rdata_reg    <= 40'b0;
		rx_data_fifo_empty_reg  <= 1'b1;
		sr_rx_fifo_empty_reg    <= 1'b1;
	end
	else begin
    	rx_data_fifo_rdata_reg  <= rx_data_fifo_rdata;
    	sr_rx_fifo_rdata_reg    <= sr_rx_fifo_rdata;
    	rx_data_fifo_empty_reg  <= rx_data_fifo_empty;
    	sr_rx_fifo_empty_reg    <= sr_rx_fifo_empty;
    end
end
//从暂存FIFO中搬移数据至片内SRAM状态机
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        c_state <= IDLE;
    end
    else begin
        c_state <= n_state;
    end
end

always @(*) begin
    case(c_state)
        IDLE:
        begin
            if (queue_indicate_ram_init_done == 1'b0) begin
                n_state = INIT;
            end
            else if ((sr_rx_fifo_empty_reg == 1'b0) && (rx_data_fifo_empty_reg == 1'b0) && (rx_data_fifo_empty == 1'b0)) begin
                n_state = WRITE_MEMORY;
            end
            else begin
                n_state = IDLE;
            end
        end
        INIT:
        begin
            if (queue_indicate_ram_init_done == 1'b1) begin
                n_state = IDLE;
            end
            else begin
                n_state = INIT;
            end
        end
        WRITE_MEMORY:
        begin
            if (write_memory_cnt == 2'd3) begin
                if (last_BD_reg == 1'b1) begin  //一帧搬移完毕，跳转至FINISH
                    n_state = WRITE_FINISH;
                end
                // else if (rx_data_fifo_empty || rx_data_fifo_empty_reg) begin  
                //     n_state = WRITE_WAIT;
                // end
                else begin
                    n_state = WRITE_MEMORY;
                end
            end
            // else if (rx_data_fifo_empty || rx_data_fifo_empty_reg) begin  
            //     n_state = WRITE_WAIT;
            // end
            else begin
                n_state = WRITE_MEMORY;
            end
        end
        // WRITE_WAIT:
        // begin
        //     if ((sr_rx_fifo_empty_reg == 1'b0) && (rx_data_fifo_empty_reg == 1'b0)) begin  //可以继续搬移这一帧的其余部分--rx_data_fifo和queue_state_fifo肯定满足条件
        //         n_state = WRITE_MEMORY;
        //     end
        //     else begin
        //         n_state = WRITE_WAIT;
        //     end
        // end
        WRITE_FINISH:
        begin
           // if ((sr_rx_fifo_empty_reg == 1'b0) && (rx_data_fifo_empty_reg == 1'b0) && (rx_data_fifo_empty == 1'b0)) begin
           //      n_state = WRITE_MEMORY;
           //  end
           //  else begin
                n_state = IDLE;
            // end
        end
        default:
        begin
            n_state = IDLE;
        end
    endcase
end

//初始化物理队长RAM
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        queue_indicate_ram_init_done <= 1'b0;
    end
    else if ((n_state == INIT) && (enqueue_indicate_length_wr_addr == 3'b111)) begin
        queue_indicate_ram_init_done <= 1'b1;
    end
    else begin
        queue_indicate_ram_init_done <= queue_indicate_ram_init_done;
    end
end

//WRITE_MEMORY状态维持计数--两拍--1,2循环计数
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        write_memory_cnt <= 2'd0;
    end
    else if (n_state == WRITE_MEMORY) begin
        write_memory_cnt <= write_memory_cnt + 2'd1;        
    end
    else if (n_state == WRITE_WAIT) begin
        write_memory_cnt <= write_memory_cnt;
    end
    else begin
        write_memory_cnt <= 2'd0;
    end
end

//拉高sr_rx_fifo读使能
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        sr_rx_fifo_rden <= 1'b0;
    end
    else if ((n_state == WRITE_MEMORY) && (write_memory_cnt == 2'd1)) begin
        sr_rx_fifo_rden <= 1'b1;
    end
    else begin
        sr_rx_fifo_rden <= 1'b0;
    end
end

assign frame_length_sub = sr_rx_fifo_rdata_reg[29:19];

//寄存端口号和优先级
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        enqueue_NodeID <= 3'd0;
        enqueue_pri    <= 3'd0;
    end
    else if ((n_state == WRITE_MEMORY) && first_BD &&(write_memory_cnt == 2'd0)) begin
        enqueue_NodeID <= sr_rx_fifo_rdata_reg[35:33];
        enqueue_pri    <= sr_rx_fifo_rdata_reg[32:30];
    end
    else begin
        enqueue_NodeID <= enqueue_NodeID ;
        enqueue_pri    <= enqueue_pri    ;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        first_BD_reg <= 1'd0;
        last_BD_reg  <= 1'd0;
    end
    else if ((n_state == WRITE_MEMORY) &&(write_memory_cnt == 2'd0)) begin
        first_BD_reg <= first_BD;
        last_BD_reg  <= last_BD ;
    end
    else begin
        first_BD_reg <= first_BD_reg;
        last_BD_reg  <= last_BD_reg ;
    end
end

//拉高rx_data_fifo读使能--首字置出
//只在写该帧最后一个BD块且使用小于等于32字节时使读使能延迟一个周期
assign rx_rd_stop = last_BD && ((c_state == WRITE_MEMORY) || (c_state == WRITE_FINISH)) && (write_memory_cnt > frame_length_sub[6:5]) /*&& (write_memory_cnt != 2'd3)*/;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        rx_data_fifo_rden <= 1'b0;
    end
    else if (rx_rd_stop) begin
        rx_data_fifo_rden <= 1'b0;                
    end
    else if ((n_state == WRITE_MEMORY) || (n_state == WRITE_FINISH)) begin
        rx_data_fifo_rden <= 1'b1;
    end
    else begin
        rx_data_fifo_rden <= 1'b0;
    end
end


//写SRAM_memory
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        memory_waddr <= 14'd0;
        memory_wren  <= 1'b0;
        memory_wdata <= 256'd0;
    end
    else if (wr_mem) begin
        if (write_memory_cnt == 2'd3) begin  //第一拍，写入BD基地址
            memory_waddr <= {sr_rx_fifo_rdata_reg[15:4],2'b0};
            memory_wren  <= 1'b1;
            memory_wdata <= rx_data_fifo_rdata_reg;
        end
        else begin
            memory_waddr <= memory_waddr + 14'd1;  //地址自增
            memory_wren  <= 1'b1;
            memory_wdata <= rx_data_fifo_rdata_reg;
        end
    end
    else begin
        memory_waddr <= 14'd0;
        memory_wren  <= 1'b0;
        memory_wdata <= 256'd0;
    end
end

//更新物理队长RAM
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        enqueue_indicate_length_wr_en  <= 1'b0;
        enqueue_indicate_length_wr_addr <= 3'd0;
        enqueue_indicate_length_wr_data <= 64'd0;
    end
    else if (n_state == INIT) begin  //物理队长RAM初始化
        if (enqueue_indicate_length_wr_addr  <= 3'd7) begin
            enqueue_indicate_length_wr_en  <= 1'b0;
            enqueue_indicate_length_wr_addr <= enqueue_indicate_length_wr_addr + 3'd1;
            enqueue_indicate_length_wr_data <= 64'd0;
        end
        else begin
            enqueue_indicate_length_wr_en  <= 1'b0;
            enqueue_indicate_length_wr_addr <= 3'd0;
            enqueue_indicate_length_wr_data <= 64'd0;
        end
    end
    else if (n_state == WRITE_MEMORY) begin
        enqueue_indicate_length_wr_en  <= 1'b0;
        enqueue_indicate_length_wr_addr <= enqueue_NodeID;
        enqueue_indicate_length_wr_data <= 64'd0;
    end
    else if (n_state == WRITE_FINISH) begin
        enqueue_indicate_length_wr_en  <= 1'b1;
        enqueue_indicate_length_wr_addr <= enqueue_NodeID;
        if ((enqueue_indicate_length_wr_addr == dequeue_indicate_length_wr_addr) && (dequeue_indicate_length_wr_en == 1'b1)) begin  //入队出队更新冲突
        case(enqueue_pri)
            3'b000: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63: 8],dequeue_indicate_length_wr_data[ 7: 0]+8'd1};
            3'b001: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:16],dequeue_indicate_length_wr_data[15: 8]+8'd1,dequeue_indicate_length_wr_data[ 7: 0]};
            3'b010: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:24],dequeue_indicate_length_wr_data[23:16]+8'd1,dequeue_indicate_length_wr_data[15: 0]};
            3'b011: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:32],dequeue_indicate_length_wr_data[31:24]+8'd1,dequeue_indicate_length_wr_data[23: 0]};
            3'b100: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:40],dequeue_indicate_length_wr_data[39:32]+8'd1,dequeue_indicate_length_wr_data[31: 0]};
            3'b101: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:48],dequeue_indicate_length_wr_data[47:40]+8'd1,dequeue_indicate_length_wr_data[39: 0]};
            3'b110: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:56],dequeue_indicate_length_wr_data[55:48]+8'd1,dequeue_indicate_length_wr_data[47: 0]};
            3'b111: enqueue_indicate_length_wr_data <= {dequeue_indicate_length_wr_data[63:56]+8'd1,dequeue_indicate_length_wr_data[55:0]};
            default:enqueue_indicate_length_wr_data <= enqueue_indicate_length_wr_data;
        endcase
        end
        else begin
        case(enqueue_pri)
            3'b000: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63: 8],enqueue_indicate_length_rd_data[ 7: 0]+8'd1};
            3'b001: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:16],enqueue_indicate_length_rd_data[15: 8]+8'd1,enqueue_indicate_length_rd_data[ 7: 0]};
            3'b010: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:24],enqueue_indicate_length_rd_data[23:16]+8'd1,enqueue_indicate_length_rd_data[15: 0]};
            3'b011: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:32],enqueue_indicate_length_rd_data[31:24]+8'd1,enqueue_indicate_length_rd_data[23: 0]};
            3'b100: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:40],enqueue_indicate_length_rd_data[39:32]+8'd1,enqueue_indicate_length_rd_data[31: 0]};
            3'b101: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:48],enqueue_indicate_length_rd_data[47:40]+8'd1,enqueue_indicate_length_rd_data[39: 0]};
            3'b110: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:56],enqueue_indicate_length_rd_data[55:48]+8'd1,enqueue_indicate_length_rd_data[47: 0]};
            3'b111: enqueue_indicate_length_wr_data <= {enqueue_indicate_length_rd_data[63:56]+8'd1,enqueue_indicate_length_rd_data[55:0]};
            default:enqueue_indicate_length_wr_data <= enqueue_indicate_length_wr_data;
        endcase 
        end
    end
    else begin
        enqueue_indicate_length_wr_en  <= 1'b0;
        enqueue_indicate_length_wr_addr <= enqueue_indicate_length_wr_addr;
        enqueue_indicate_length_wr_data <= 64'd0;
    end
end

//置位对应端口的1bit
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        port_state_bit_set <= 3'd0;
        port_state_bit_val <= 1'b0;
    end
    else if (n_state == WRITE_FINISH) begin
        port_state_bit_set <= enqueue_NodeID;
        port_state_bit_val <= 1'b1;
    end
    else begin
        port_state_bit_set <= 3'd0;
        port_state_bit_val <= 1'b0;
    end
end



//mark_debug
`ifndef ASIC
(*mark_debug = "true"*) reg [31:0] bus_rx_cnt;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        bus_rx_cnt <= 32'd0;
    end
    else if (c_state == WRITE_MEMORY && n_state == WRITE_FINISH) begin
        bus_rx_cnt <= bus_rx_cnt + 1'b1;
    end
    else begin
        bus_rx_cnt <= bus_rx_cnt;
    end
end

(*mark_debug = "true"*) reg [31:0] discard_cnt;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        discard_cnt <= 32'd0;
    end
    else if (cstate == TRANS_DISCARD && nstate == TRANS_IDLE) begin
        discard_cnt <= discard_cnt + 1'b1;
    end
    else begin
        discard_cnt <= discard_cnt;
    end
end
`endif

`ifdef SIM 
integer enqueue_data;
initial
begin
    enqueue_data = $fopen("enqueue_data.txt");
end

always @(posedge clk) begin
    if (bus_data_val_i) begin
        $fwrite(enqueue_data,"%h\n",bus_data_i);
    end
end

initial
begin
    wait(bus_rx_cnt == `SEND_NUM && c_state == IDLE)
        $fclose(enqueue_data);
end
`endif

endmodule
